#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"code.h"
//基本块定义入口语句和出口语句
//入口语句：第一句；有无条件转移语句跳转到的语句；紧跟在条件语句后的语句
//出口语句：下一个入口语句的前一句；转移（条件）语句本身；停语句本身
struct node{
	char op[20];
	char arg1[10];
	char arg2[10];
	char result[10];
};
int main()
{	
	int	in[20],out[20]; 
	FILE *fp=fopen("midCodeFile.txt","r");//以文本方式打开 
	struct node four[100];
	char order[100][40],buf[40];
	int temp=0;//计算有几行三地址代码 
	
	while(fp!=NULL)//逐行读取存入字符数组中 
	{
		if(fgets(buf,40,fp)!=NULL)
		{
			buf[strlen(buf)-1]='\0';
			strcpy(order[temp],buf);
			temp++;
		}
		else
		{
			break;
		}
	}
	free(fp);
	
	char (*p)[40]=order;//二维数组指针
	for(int i=0;i<temp;i++)//
	{
		printf("%s\n",p[i]);//逐行输出三地址代码，查看是否正确 
	 } 
	 for(int i=0;i<temp;i++)
	 {
	 	int count=0,templine=0;//逐列分开 
	 	char line[30];
	 	strcpy(line,order[i]);
	 	char *a=line;
	 	while(*(a+i)!=' ')
		{
			four[i].op[templine]=line[count];
			templine++;
			count++; 
		}	
		count++;//跳过空格 
		templine=0;
		while(*(a+i)!=' ')
		{
			four[i].arg1[templine]=line[count];
			templine++;
			count++; 
		}
		count++;
		templine=0;
		while(*(a+i)!=' ')
		{
			four[i].arg2[templine]=line[count];
			templine++;
			count++; 
			}
		count++;
		templine=0;
		while(*(a+i)!='\0')
		{
			four[i].result[count]=line[count];
			templine++;
			count++; 
			}	
	 }
	 int block=1;
	 int begin=1,end=1;
	 in[0]=begin;//第一个语句就是入口语句1
	 out[0]=end;//Out[0]暂定=1，第二个入口语句的前一句是out[0] 
	 int recordline=1;
	 for(int i=0;i<temp;i++)
	 {	
	 	recordline=i;
		 if(strcmp(four[i].op,"GOTO")==0)
		 {
		 	end=i;//出口语句2 
		 	out[block-1]=end;
		 	//查找跳转到的语句 ，入口语句2 
			for(int j=0;j<temp;j++)
			{
				if((strcmp(four[j].arg1,four[i].arg1)==0)&&(strcmp(four[j].op,"LABEL")==0))
				{
					in[block]=j;//LABEL去除 
				}
			}
	        begin=i+2;//入口语句3,条件语句的下一句,跳过LABEL
	        in[block+1]=begin;

	        block++;
		  } 
		  if(strcmp(four[i].op,"PROGRAM_BODY_END")==0)
		  {
		  	out[block-1]=i;//出口语句3 
		  }
		
	 		
	 }
	 for(int i=0;i<block;i++)
		{
			printf("Block[%d]:	",i+1);
			printf("出口语句%d	",in[i]);
			printf("入口语句%d",out[i]);
		 } 
/*符号表划分为全局符号表，局部符号表
子程序、函数名和公共区变量填入全局符号表
子程序函数声明的标识符开始构造局部符号表
在语句部分督导标识符，查表
子程序结束时释放对应的局部符号表
PROGRAM_END程序结束时释放所有表
*/
//对每个基本块从最后一个语句反向扫描到第一个语句，得到下次引用信息，判断后面是否还有引用做出相应的编译优化
//建立全局符号表
LinkTable totaltableptr=init();
//TODO逐行扫描填入子程序，函数名、公共区变量
for(int i=0;i<temp;i++)
{	
	if(strcmp(four[i].op,"SUB_PROGRAM_START")==0)//子函数开始，建立子表
	{
		for(int templine=i;strcmp((four[templine].op),"SUB_PROGRAM_END")!=0;templine++)
		{
			//TODO建立子表
			LinkTable subtableptr=init();
		}
	}
	//语句部分查表

}
	return 0;
}
